package com.ruicar.afs.cloud.afscase.job.loan;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseContractInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseContractInfoService;
import com.ruicar.afs.cloud.afscase.interfacerecord.service.CaseOcrInterfaceRecordService;
import com.ruicar.afs.cloud.afscase.interfacerecord.vo.InvoiceCarOcrDiscernVo;
import com.ruicar.afs.cloud.afscase.loanapprove.entity.CarInvoiceInfo;
import com.ruicar.afs.cloud.afscase.loanapprove.service.CarInvoiceInfoService;
import com.ruicar.afs.cloud.afscase.loanapprove.vo.InvoiceCheckVo;
import com.ruicar.afs.cloud.common.job.core.biz.model.ReturnT;
import com.ruicar.afs.cloud.common.job.core.handler.annotation.AfsJob;
import com.ruicar.afs.cloud.common.job.core.handler.annotation.AfsJobHandler;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.OcrTypeEnum;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.WhetherEnum;
import com.ruicar.afs.cloud.image.condition.OcrDiscernCondition;
import com.ruicar.afs.cloud.image.entity.ComAttachmentFile;
import com.ruicar.afs.cloud.image.enums.AttachmentUniqueCodeEnum;
import com.ruicar.afs.cloud.image.service.ComAttaManageService;
import com.ruicar.afs.cloud.invoice.config.InvoiceTokenProperties;
import com.ruicar.afs.cloud.invoice.dto.InvoiceCheckDto;
import com.ruicar.afs.cloud.invoice.feign.InvoiceApiFeign;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description: 发票验证定时任务
 * @author: rongji.zhang
 * @date: 2020/8/24 17:53
 */
@Slf4j
@Component
@AfsJob
@RestController
@AllArgsConstructor
@ApiOperation(value = "发票验证定时任务")
public class InvoiceVerificationJob {

    private final String inletEnd="PC";

    private final String sysCode="BOSS";
    private ComAttaManageService comAttaManageService;
    private CaseContractInfoService caseContractInfoService;
    private CarInvoiceInfoService carInvoiceInfoService;
    private CaseOcrInterfaceRecordService caseOcrInterfaceRecordService;
    private InvoiceTokenProperties invoiceTokenProperties;
    private InvoiceApiFeign invoiceApiFeign;

    @AfsJobHandler(value = "invoiceVerificationAuto")
    public ReturnT<String> invoiceVerificationAuto(String param) {
        try {
            log.info("*************************************************发票验证定时任务开始*********************************************************");
            Date now = new Date();
            Date date = DateUtils.addDays(now, -30);
            LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
            //获取30天前最小时间 xxxx-xx-xx 0:00:00
            LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
            log.info("获取30天前最小时间{}",startOfDay);
            //获取30天前最大时间 xxxx-xx-xx 23:59:59
            LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
            log.info("获取30天前最大时间{}",endOfDay);
            Date startDate = Date.from(startOfDay.atZone( ZoneId.systemDefault()).toInstant());
            Date endDate = Date.from(endOfDay.atZone( ZoneId.systemDefault()).toInstant());
            List<CaseContractInfo> caseContractInfoList= caseContractInfoService.list(Wrappers.<CaseContractInfo>query().lambda()
                    .between(CaseContractInfo::getLendingPassDate,startDate,endDate));
            if(CollectionUtils.isNotEmpty(caseContractInfoList)){
                log.info("*************************************************检测到{}单符合二次发票验证的案件*********************************************************",caseContractInfoList.size());
                caseContractInfoList.forEach(caseContractInfo->{
                    CarInvoiceInfo carInvoiceInfo=carInvoiceInfoService.getOne(Wrappers.<CarInvoiceInfo>query().lambda()
                            .eq(CarInvoiceInfo::getContractNo,caseContractInfo.getContractNo()));
                    InvoiceCarOcrDiscernVo invoiceCarOcrDiscernVo = this.getInvoiceOCR(carInvoiceInfo);
                    if(ObjectUtils.isNotEmpty(invoiceCarOcrDiscernVo)){
                        this.getInvoiceCheck(invoiceCarOcrDiscernVo,caseContractInfo);
                    } else {
                        CarInvoiceInfo newCarInvoiceInfo = carInvoiceInfoService.getOne(Wrappers.<CarInvoiceInfo>query().lambda()
                                .eq(CarInvoiceInfo::getContractNo, caseContractInfo.getContractNo()));
                        if(ObjectUtils.isNotEmpty(newCarInvoiceInfo)){
                            newCarInvoiceInfo.setInvoiceVerificationResult(WhetherEnum.NO.getCode());
                            newCarInvoiceInfo.setInvoiceVerificationResultDesc("OCR验证获取图片失败");
                            carInvoiceInfoService.updateById(newCarInvoiceInfo);
                        }
                    }
                });
            }else {
                log.info("************************************************未检测到符合的案件*********************************************************");
            }
            log.info("*************************************************发票验证定时任务结束*********************************************************");
            return ReturnT.SUCCESS;
        }catch (Exception e){
            log.error("*************************************************发票验证定时任务失败*********************************************************",e);
            return ReturnT.FAIL;
        }
    }

    public InvoiceCarOcrDiscernVo getInvoiceOCR(CarInvoiceInfo carInvoiceInfo){
        OcrDiscernCondition dto=new OcrDiscernCondition();
        ComAttachmentFile file = comAttaManageService.getFile(AttachmentUniqueCodeEnum.CAR_INVOICE.getCode(), carInvoiceInfo.getContractNo());
        dto.setCaseCode(carInvoiceInfo.getContractNo());
        dto.setInletEnd(inletEnd);
        dto.setSysCode(sysCode);
        dto.setFileCode(OcrTypeEnum.INVOICE_CAR.getValue());
        dto.setFileMd5(file.getFileId() == null ? "" : file.getFileId());
        InvoiceCarOcrDiscernVo invoiceCarOcrDiscernVo = caseOcrInterfaceRecordService.getInvoiceCarOcrDiscern(dto);
        if(invoiceCarOcrDiscernVo !=null) {
            String price = invoiceCarOcrDiscernVo.getPrice().replaceAll("[^\\d.]+","");
            carInvoiceInfo.setInvoiceCode(invoiceCarOcrDiscernVo.getMachineCode());
            carInvoiceInfo.setInvoiceNumber(invoiceCarOcrDiscernVo.getMachineNumber());
            try {
                carInvoiceInfo.setInvoiceAmt(new BigDecimal(price));
            }catch (Exception e){
                e.printStackTrace();
            }
            String time = "9999-12-31";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            try {
                Date date = sdf.parse(time);
                if(invoiceCarOcrDiscernVo.getInvoiceDate()!=null && !invoiceCarOcrDiscernVo.getInvoiceDate().equals(date)){
                    carInvoiceInfo.setInvoiceDate(invoiceCarOcrDiscernVo.getInvoiceDate());
                }
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            carInvoiceInfoService.updateById(carInvoiceInfo);
        }
        return (null!=invoiceCarOcrDiscernVo?invoiceCarOcrDiscernVo:null);
    }

    public void getInvoiceCheck(InvoiceCarOcrDiscernVo invoiceCarOcrDiscernVo,CaseContractInfo caseContractInfo){
        String price = invoiceCarOcrDiscernVo.getPrice().replaceAll("[^\\d.]+","");
        InvoiceCheckDto invoiceCheckDto = new InvoiceCheckDto();
        invoiceCheckDto.setCode(invoiceCarOcrDiscernVo.getMachineCode());
        invoiceCheckDto.setNumber(invoiceCarOcrDiscernVo.getMachineNumber());
        invoiceCheckDto.setTime(invoiceCarOcrDiscernVo.getInvoiceDate().toString());
        invoiceCheckDto.setTotal(price);
        invoiceCheckDto.setVerifyNo("");
        Map<String, String> headers = new HashMap<String, String>();
        headers.put("Content-Type", "application/json");
        headers.put("X-Auth-Token", invoiceTokenProperties.getToken());
        JSONObject invoiceCheck = invoiceApiFeign.InvoiceCheck(invoiceCheckDto, headers);
        InvoiceCheckVo invoiceCheckVo = new InvoiceCheckVo();
        invoiceCheckVo.setCode(invoiceCheck.getString("code"));
        invoiceCheckVo.setMessage(invoiceCheck.getString("message"));
        invoiceCheckVo.setAnalyzeId(invoiceCheck.getString("analyzeId"));
        invoiceCheckVo.setMachinePrintedCode(invoiceCarOcrDiscernVo.getMachineCode());
        invoiceCheckVo.setMachineNumber(invoiceCarOcrDiscernVo.getMachineNumber());
        invoiceCheckVo.setTotalPriceTax(invoiceCarOcrDiscernVo.getPrice());
        CarInvoiceInfo carInvoiceInfo=carInvoiceInfoService.getOne(Wrappers.<CarInvoiceInfo>query().lambda()
                .eq(CarInvoiceInfo::getContractNo,caseContractInfo.getContractNo()));
        if (invoiceCheckVo.getCode().equals("0")) {
            carInvoiceInfo.setInvoiceCode(invoiceCarOcrDiscernVo.getMachineCode());
            carInvoiceInfo.setInvoiceNumber(invoiceCarOcrDiscernVo.getMachineNumber());
            try {
                carInvoiceInfo.setInvoiceAmt(new BigDecimal(invoiceCheckDto.getTotal()));
            }catch (Exception e){
                e.printStackTrace();
            }
            String time = "9999-12-31";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            try {
                Date date = sdf.parse(time);
                if(invoiceCarOcrDiscernVo.getInvoiceDate()!=null && !invoiceCarOcrDiscernVo.getInvoiceDate().equals(date)){
                    carInvoiceInfo.setInvoiceDate(invoiceCarOcrDiscernVo.getInvoiceDate());
                }
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            carInvoiceInfo.setInvoiceVerificationResult(WhetherEnum.YES.getCode());
            carInvoiceInfo.setInvoiceVerificationResultDesc(invoiceCheckVo.getMessage());
        } else {
            carInvoiceInfo.setInvoiceVerificationResult(WhetherEnum.NO.getCode());
            carInvoiceInfo.setInvoiceVerificationResultDesc(invoiceCheckVo.getMessage());
        }
        carInvoiceInfoService.updateById(carInvoiceInfo);
    }
}
